package programa;

import java.util.Vector;

import excepciones.ExcepcionCantidadDeTarjetasAmarillasIncorrecta;
import excepciones.ExcepcionNumeroDeFechaImposible;

import programa.DatosDeUnaFechaDeUnJugador;

public abstract class Jugador{
	
	//ATRIBUTOS CONSTANTES
	protected static int cantidadMinimaDeFechas = 1;
	protected static int cantidadTotalDeFechas = 19;
	protected static int puntajePorGolDePenal = 2;
	protected static int puntajePorPenalErrado = -2;
	protected static int puntajePorGolEnContra = -3;
	protected static int puntajePorTarjetaAmarilla = -1;
	protected static int puntajePorTarjetaRoja = -2;
	protected static int puntajePorSalirFigura = 2;
	protected static int puntajePorSalirChenemigo = -2;
	
	//ATRIBUTOS VARIABLES
	private String nombre;
	private int valorDeMercado;
	protected Vector<DatosDeUnaFechaDeUnJugador> datosPorFechaDelJugador;
	protected int puntajePorGolAfavor;
	
	//METODOS ABSTRACTOS
	
	protected abstract void agregateAlEquipo(Equipo unEquipo);
	protected abstract boolean quitateDelEquipo(Equipo unEquipo);
	
	//METODOS INTERNOS
	protected void crearYllenarLosDatosPorFechaDeUnJugador(){
		
		this.datosPorFechaDelJugador = new Vector<DatosDeUnaFechaDeUnJugador>(cantidadTotalDeFechas);
		
		for(int i = 0; i < cantidadTotalDeFechas; i++){
			
			this.datosPorFechaDelJugador.insertElementAt(new DatosDeUnaFechaDeUnJugador(), i);
			
		}
		
	}
	
	//************************************************************************
	
	protected void corroborarSiEstaEnElRangoCorrectoLaFecha(int unaFecha)throws ExcepcionNumeroDeFechaImposible{
		
		if(unaFecha < cantidadMinimaDeFechas || unaFecha > cantidadTotalDeFechas){
			
			throw new ExcepcionNumeroDeFechaImposible();
			
		}
		
	}
	
	//************************************************************************
	
	private int calcularYobtenerPuntajeTotalParaLaFecha(int unaFecha){
		
		double puntajeFinal = 0;
		
		puntajeFinal += this.datosPorFechaDelJugador.get(unaFecha -1).obtenerPuntajeDelPartido();
		
		puntajeFinal += (this.datosPorFechaDelJugador.get(unaFecha -1).obtenerCantidadDeGolesDeJugadaAfavorRealizados() * this.puntajePorGolAfavor);
		
		puntajeFinal += (this.datosPorFechaDelJugador.get(unaFecha - 1).obtenerCantidadDeGolesDePenalRealizados() * puntajePorGolDePenal);
		
		puntajeFinal += (this.datosPorFechaDelJugador.get(unaFecha - 1).obtenerCantidadDeGolesEnContraRealizados() * puntajePorGolEnContra);
		
		puntajeFinal += (this.datosPorFechaDelJugador.get(unaFecha - 1).obtenerCantidadDePenalesErrados() * puntajePorPenalErrado);
		
		if(this.datosPorFechaDelJugador.get(unaFecha - 1).jugadorFueExpulsado()){
			
			puntajeFinal += puntajePorTarjetaRoja;
			
		}else{
			
			puntajeFinal += (this.datosPorFechaDelJugador.get(unaFecha - 1).obtenerCantidadDeTarjetasAmarillas() * puntajePorTarjetaAmarilla);
			
		}
		
		if(this.datosPorFechaDelJugador.get(unaFecha - 1).jugadorFueFigura()){
			
			puntajeFinal += puntajePorSalirFigura;
			
		}
		
		if(this.datosPorFechaDelJugador.get(unaFecha - 1).jugadorFueChenemigo()){
			
			puntajeFinal += puntajePorSalirChenemigo;
			
		}
		
		return (int)puntajeFinal;
		
	}
	
	//METODOS PUBLICOS
	public Jugador(String unNombre, int unValorDeMercado){
		
		this.nombre = unNombre;
		
		this.valorDeMercado = unValorDeMercado;
		
		this.crearYllenarLosDatosPorFechaDeUnJugador();
		
	}
	
	//****************************************************************************
	
	public void recibioPuntajeEnLaFecha(double unPuntaje, int unaFecha)throws ExcepcionNumeroDeFechaImposible{
		
		try{
			
			this.corroborarSiEstaEnElRangoCorrectoLaFecha(unaFecha);
			
			DatosDeUnaFechaDeUnJugador unosDatosDeUnaFechaDelJugador;
			
			unosDatosDeUnaFechaDelJugador = this.datosPorFechaDelJugador.get(unaFecha - 1);
			
			unosDatosDeUnaFechaDelJugador.jugadorRecibioPuntaje(unPuntaje);
					
			this.datosPorFechaDelJugador.insertElementAt(unosDatosDeUnaFechaDelJugador, unaFecha - 1);
			
		}catch(ExcepcionNumeroDeFechaImposible miExcepcion){
			
			throw miExcepcion;
			
		}
		
	}
	
	//****************************************************************************
	
	public void hizoCantidadDeGolesDeJugadaAfavorEnLaFecha(int unaCantidadDeGoles, int unaFecha) throws ExcepcionNumeroDeFechaImposible{
		
		try{
			
			this.corroborarSiEstaEnElRangoCorrectoLaFecha(unaFecha);
			
			DatosDeUnaFechaDeUnJugador unosDatosDeUnaFechaDelJugador;
			
			unosDatosDeUnaFechaDelJugador = this.datosPorFechaDelJugador.get(unaFecha - 1);
			
			unosDatosDeUnaFechaDelJugador.jugadorHizoCantidadDeGolesDeJugadaAfavor(unaCantidadDeGoles);
					
			this.datosPorFechaDelJugador.insertElementAt(unosDatosDeUnaFechaDelJugador, unaFecha - 1);
			
		}catch(ExcepcionNumeroDeFechaImposible miExcepcion){
			
			throw miExcepcion;
			
		}
		
	}
	
	//****************************************************************************
	
	public void hizoCantidadDeGolesDePenalEnLaFecha(int unaCantidadDeGoles, int unaFecha) throws ExcepcionNumeroDeFechaImposible{
		
		try{
			
			this.corroborarSiEstaEnElRangoCorrectoLaFecha(unaFecha);
			
			DatosDeUnaFechaDeUnJugador unosDatosDeUnaFechaDelJugador;
			
			unosDatosDeUnaFechaDelJugador = this.datosPorFechaDelJugador.get(unaFecha - 1);
			
			unosDatosDeUnaFechaDelJugador.jugadorHizoCantidadDeGolesDePenal(unaCantidadDeGoles);
					
			this.datosPorFechaDelJugador.insertElementAt(unosDatosDeUnaFechaDelJugador, unaFecha - 1);
			
		}catch(ExcepcionNumeroDeFechaImposible miExcepcion){
			
			throw miExcepcion;
			
		}

	}

	//****************************************************************************

	public void erroCantidadDePenalesEnLaFecha(int unaCantidadDePenales, int unaFecha) throws ExcepcionNumeroDeFechaImposible{
		
		try{
			
			this.corroborarSiEstaEnElRangoCorrectoLaFecha(unaFecha);
			
			DatosDeUnaFechaDeUnJugador unosDatosDeUnaFechaDelJugador;
				
			unosDatosDeUnaFechaDelJugador = this.datosPorFechaDelJugador.get(unaFecha - 1);
		
			unosDatosDeUnaFechaDelJugador.jugadorErroCantidadDePenales(unaCantidadDePenales);
				
			this.datosPorFechaDelJugador.insertElementAt(unosDatosDeUnaFechaDelJugador, unaFecha - 1);
		
		}catch(ExcepcionNumeroDeFechaImposible miExcepcion){
			
			throw miExcepcion;
			
		}
		
	}
	
	//****************************************************************************
	
	public void hizoCantidadDeGolesEnContraEnLaFecha(int unaCantidadDeGoles, int unaFecha) throws ExcepcionNumeroDeFechaImposible{
		
		try{
			
			this.corroborarSiEstaEnElRangoCorrectoLaFecha(unaFecha);
			
			DatosDeUnaFechaDeUnJugador unosDatosDeUnaFechaDelJugador;
			
			unosDatosDeUnaFechaDelJugador = this.datosPorFechaDelJugador.get(unaFecha - 1);
			
			unosDatosDeUnaFechaDelJugador.jugadorHizoCantidadDeGolesEnContra(unaCantidadDeGoles);
					
			this.datosPorFechaDelJugador.insertElementAt(unosDatosDeUnaFechaDelJugador, unaFecha - 1);
			
		}catch(ExcepcionNumeroDeFechaImposible miExcepcion){
			
			throw miExcepcion;
			
		}
		
	}
	
	public void obtuvoCantidadDeTarjetasAmarillasEnLaFecha(int unaCantidadDeTarjetasAmarillas, int unaFecha) throws ExcepcionCantidadDeTarjetasAmarillasIncorrecta, ExcepcionNumeroDeFechaImposible{
		
		try{
			
			this.corroborarSiEstaEnElRangoCorrectoLaFecha(unaFecha);
			
			DatosDeUnaFechaDeUnJugador unosDatosDeUnaFechaDelJugador;
			
			unosDatosDeUnaFechaDelJugador = this.datosPorFechaDelJugador.get(unaFecha - 1);
			
			try{
				
				unosDatosDeUnaFechaDelJugador.jugadorObtuvoCantidadDeTarjetasAmarillas(unaCantidadDeTarjetasAmarillas);
				
				this.datosPorFechaDelJugador.insertElementAt(unosDatosDeUnaFechaDelJugador, unaFecha - 1);
				
			}catch(ExcepcionCantidadDeTarjetasAmarillasIncorrecta miExcepcion){
				
				throw miExcepcion;
				
			}
			
		}catch(ExcepcionNumeroDeFechaImposible miExcepcion){
			
			throw miExcepcion;
			
		}
	
	}
	
	//*************************************************************************
	
	public void salioExpulsadoEnLaFecha(int unaFecha) throws ExcepcionNumeroDeFechaImposible{
		
		try{
			
			this.corroborarSiEstaEnElRangoCorrectoLaFecha(unaFecha);
			
			DatosDeUnaFechaDeUnJugador unosDatosDeUnaFechaDelJugador;
			
			unosDatosDeUnaFechaDelJugador = this.datosPorFechaDelJugador.get(unaFecha - 1);

			unosDatosDeUnaFechaDelJugador.jugadorSalioExpulsado();
					
			this.datosPorFechaDelJugador.insertElementAt(unosDatosDeUnaFechaDelJugador, unaFecha - 1);
			
		}catch(ExcepcionNumeroDeFechaImposible miExcepcion){
			
			throw miExcepcion;
			
		}	
		
	}
	
	//*************************************************************************
	
	public void salioFiguraEnLaFecha(int unaFecha) throws ExcepcionNumeroDeFechaImposible{
		
		try{
			
			this.corroborarSiEstaEnElRangoCorrectoLaFecha(unaFecha);
			
			DatosDeUnaFechaDeUnJugador unosDatosDeUnaFechaDelJugador;
			
			unosDatosDeUnaFechaDelJugador = this.datosPorFechaDelJugador.get(unaFecha - 1);

			unosDatosDeUnaFechaDelJugador.jugadorSalioFigura();
					
			this.datosPorFechaDelJugador.insertElementAt(unosDatosDeUnaFechaDelJugador, unaFecha - 1);
			
		}catch(ExcepcionNumeroDeFechaImposible miExcepcion){
			
			throw miExcepcion;
			
		}	
		
	}
	
	//****************************************************************************
	
	public void salioChenemigoEnLaFecha(int unaFecha) throws ExcepcionNumeroDeFechaImposible{
			
		try{
			
			this.corroborarSiEstaEnElRangoCorrectoLaFecha(unaFecha);
			
			DatosDeUnaFechaDeUnJugador unosDatosDeUnaFechaDelJugador;
			
			unosDatosDeUnaFechaDelJugador = this.datosPorFechaDelJugador.get(unaFecha - 1);

			unosDatosDeUnaFechaDelJugador.jugadorSalioChenemigo();
						
			this.datosPorFechaDelJugador.insertElementAt(unosDatosDeUnaFechaDelJugador, unaFecha - 1);
				
		}catch(ExcepcionNumeroDeFechaImposible miExcepcion){
			
			throw miExcepcion;
			
		}	

	}
	
	//****************************************************************************
	
	public int obtenerValorDeMercado(){
		
		return this.valorDeMercado;
		
	}
	
	//****************************************************************************
	
	public String obtenerNombre(){
		
		return this.nombre;
		
	}
	
	//****************************************************************************
	
	public double obtenerPuntajeDelPartidoDeLaFecha(int unaFecha) throws ExcepcionNumeroDeFechaImposible{
		
		try{
			
			this.corroborarSiEstaEnElRangoCorrectoLaFecha(unaFecha);
			
			return (this.datosPorFechaDelJugador.get(unaFecha - 1).obtenerPuntajeDelPartido());
			
		}catch(ExcepcionNumeroDeFechaImposible miExcepcion){
			
			throw miExcepcion;
			
		}	
		
	}
	
	//****************************************************************************
	
	public int obtenerCantidadDeGolesDeJugadaAfavorDeLaFecha(int unaFecha) throws ExcepcionNumeroDeFechaImposible{
			
		try{
			
			this.corroborarSiEstaEnElRangoCorrectoLaFecha(unaFecha);
			
			return (this.datosPorFechaDelJugador.get(unaFecha - 1).obtenerCantidadDeGolesDeJugadaAfavorRealizados());
			
		}catch(ExcepcionNumeroDeFechaImposible miExcepcion){
			
			throw miExcepcion;
			
		}	
			
	}
	
	//****************************************************************************
	
	public int obtenerCantidadDeGolesDePenalDeLaFecha(int unaFecha) throws ExcepcionNumeroDeFechaImposible{
				
		try{
			
			this.corroborarSiEstaEnElRangoCorrectoLaFecha(unaFecha);
			
			return (this.datosPorFechaDelJugador.get(unaFecha - 1).obtenerCantidadDeGolesDePenalRealizados());
			
		}catch(ExcepcionNumeroDeFechaImposible miExcepcion){
			
			throw miExcepcion;
			
		}	
		
	}
		
	//****************************************************************************
		
	public int obtenerCantidadDePenalesErradosDeLaFecha(int unaFecha) throws ExcepcionNumeroDeFechaImposible{
				
		try{
			
			this.corroborarSiEstaEnElRangoCorrectoLaFecha(unaFecha);
			
			return (this.datosPorFechaDelJugador.get(unaFecha - 1).obtenerCantidadDePenalesErrados());
			
		}catch(ExcepcionNumeroDeFechaImposible miExcepcion){
			
			throw miExcepcion;
			
		}	
				
	}
	
	//****************************************************************************
	
	public int obtenerCantidadDeGolesEnContraDeLaFecha(int unaFecha) throws ExcepcionNumeroDeFechaImposible{
				
		try{
			
			this.corroborarSiEstaEnElRangoCorrectoLaFecha(unaFecha);
			
			return (this.datosPorFechaDelJugador.get(unaFecha - 1).obtenerCantidadDeGolesEnContraRealizados());
			
		}catch(ExcepcionNumeroDeFechaImposible miExcepcion){
			
			throw miExcepcion;
			
		}	
				
	}
	
	//****************************************************************************
	
	public int obtenerCantidadDeTarjetasAmarillasDeLaFecha(int unaFecha) throws ExcepcionNumeroDeFechaImposible{
		
		try{
			
			this.corroborarSiEstaEnElRangoCorrectoLaFecha(unaFecha);
			
			return (this.datosPorFechaDelJugador.get(unaFecha - 1).obtenerCantidadDeTarjetasAmarillas());
			
		}catch(ExcepcionNumeroDeFechaImposible miExcepcion){
			
			throw miExcepcion;
			
		}	
		
	}
	
	//****************************************************************************
	
	public boolean fueExpulsadoEnLaFecha(int unaFecha) throws ExcepcionNumeroDeFechaImposible{
		
		try{
			
			this.corroborarSiEstaEnElRangoCorrectoLaFecha(unaFecha);
			
			return (this.datosPorFechaDelJugador.get(unaFecha - 1).jugadorFueExpulsado());
			
		}catch(ExcepcionNumeroDeFechaImposible miExcepcion){
			
			throw miExcepcion;
			
		}	
		
	}
	
	//****************************************************************************
	
	public boolean fueFiguraEnLaFecha(int unaFecha) throws ExcepcionNumeroDeFechaImposible{
		
		try{
			
			this.corroborarSiEstaEnElRangoCorrectoLaFecha(unaFecha);
			
			return (this.datosPorFechaDelJugador.get(unaFecha - 1).jugadorFueFigura());
			
		}catch(ExcepcionNumeroDeFechaImposible miExcepcion){
			
			throw miExcepcion;
			
		}	
		
	}
	
	//****************************************************************************
	
	public boolean fueChenemigoEnLaFecha(int unaFecha) throws ExcepcionNumeroDeFechaImposible{
			
		try{
			
			this.corroborarSiEstaEnElRangoCorrectoLaFecha(unaFecha);
			
			return (this.datosPorFechaDelJugador.get(unaFecha - 1).jugadorFueChenemigo());
			
		}catch(ExcepcionNumeroDeFechaImposible miExcepcion){
			
			throw miExcepcion;
			
		}	
			
	}
	
	//****************************************************************************
	
	public int obtenerPuntajeTotalDeLaFecha(int unaFecha) throws ExcepcionNumeroDeFechaImposible{
		
		try{
			
			this.corroborarSiEstaEnElRangoCorrectoLaFecha(unaFecha);
			
			return (this.calcularYobtenerPuntajeTotalParaLaFecha(unaFecha));
			
		}catch(ExcepcionNumeroDeFechaImposible miExcepcion){
			
			throw miExcepcion;
			
		}	
			
	}
	
	//*************************************************************************

}
